#include "Losa.h"


Losa::Losa() {
	// La losa esta formada por 2 capas unidas en forma tridimensional
	// Cada capa esta formada por 4 cuadrados formados por 2 triangulos

	// Cara superior
	this->m_vertices_caraSuperior[0] = glm::vec3(-5.0f, 10.0f, 0.25f);
	this->m_vertices_caraSuperior[1] = glm::vec3(5.0f, 10.0f, 0.25f);
	this->m_vertices_caraSuperior[2] = glm::vec3(-5.0f, -6.0f, 0.25f);
	this->m_vertices_caraSuperior[3] = glm::vec3(1.0f, -6.0f, 0.25f);

	this->m_vertices_caraSuperior[4] = glm::vec3(4.0f, -6.0f, 0.25f);
	this->m_vertices_caraSuperior[5] = glm::vec3(5.0f, -6.0f, 0.25f);
	this->m_vertices_caraSuperior[6] = glm::vec3(1.0f, -9.0f, 0.25f);
	this->m_vertices_caraSuperior[7] = glm::vec3(4.0f, -9.0f, 0.25f);

	this->m_vertices_caraSuperior[8] = glm::vec3(5.0f, -9.0f, 0.25f);
	this->m_vertices_caraSuperior[9] = glm::vec3(-5.0f, -10.0f, 0.25f);
	this->m_vertices_caraSuperior[10] = glm::vec3(1.0f, -10.0f, 0.25f);
	this->m_vertices_caraSuperior[11] = glm::vec3(5.0f, -10.0f, 0.25f);

	// Las normales de la cara superior
	for (int i = 0; i < 12; ++i) this->m_normales_caraSuperior[i] = glm::vec3(0.0f, 0.0f, 1.0f);

	// Indices de la cara superior
	this->m_IndexBuff_caraSuperior[0] = 0;
	this->m_IndexBuff_caraSuperior[1] = 1;
	this->m_IndexBuff_caraSuperior[2] = 2;
	this->m_IndexBuff_caraSuperior[3] = 1;
	this->m_IndexBuff_caraSuperior[4] = 2;
	this->m_IndexBuff_caraSuperior[5] = 5;

	this->m_IndexBuff_caraSuperior[6] = 2;
	this->m_IndexBuff_caraSuperior[7] = 3;
	this->m_IndexBuff_caraSuperior[8] = 9;
	this->m_IndexBuff_caraSuperior[9] = 3;
	this->m_IndexBuff_caraSuperior[10] = 9;
	this->m_IndexBuff_caraSuperior[11] = 10;

	this->m_IndexBuff_caraSuperior[12] = 6;
	this->m_IndexBuff_caraSuperior[13] = 8;
	this->m_IndexBuff_caraSuperior[14] = 10;
	this->m_IndexBuff_caraSuperior[15] = 8;
	this->m_IndexBuff_caraSuperior[16] = 10;
	this->m_IndexBuff_caraSuperior[17] = 11;

	this->m_IndexBuff_caraSuperior[18] = 7;
	this->m_IndexBuff_caraSuperior[19] = 8;
	this->m_IndexBuff_caraSuperior[20] = 5;
	this->m_IndexBuff_caraSuperior[21] = 7;
	this->m_IndexBuff_caraSuperior[22] = 5;
	this->m_IndexBuff_caraSuperior[23] = 4;

	// Cara inferior
	this->m_vertices_caraInferior[0] = glm::vec3(-5.0f, 10.0f, -0.25f);
	this->m_vertices_caraInferior[1] = glm::vec3(5.0f, 10.0f, -0.25f);
	this->m_vertices_caraInferior[2] = glm::vec3(-5.0f, -6.0f, -0.25f);
	this->m_vertices_caraInferior[3] = glm::vec3(1.0f, -6.0f, -0.25f);

	this->m_vertices_caraInferior[4] = glm::vec3(4.0f, -6.0f, -0.25f);
	this->m_vertices_caraInferior[5] = glm::vec3(5.0f, -6.0f, -0.25f);
	this->m_vertices_caraInferior[6] = glm::vec3(1.0f, -9.0f, -0.25f);
	this->m_vertices_caraInferior[7] = glm::vec3(4.0f, -9.0f, -0.25f);

	this->m_vertices_caraInferior[8] = glm::vec3(5.0f, -9.0f, -0.25f);
	this->m_vertices_caraInferior[9] = glm::vec3(-5.0f, -10.0f, -0.25f);
	this->m_vertices_caraInferior[10] = glm::vec3(1.0f, -10.0f, -0.25f);
	this->m_vertices_caraInferior[11] = glm::vec3(5.0f, -10.0f, -0.25f);

	// Las normales de la cara inferior
	for (int i = 0; i < 12; ++i) this->m_normales_caraInferior[i] = glm::vec3(0.0f, 0.0f, -1.0f);

	// Indices de la cara inferior
	this->m_IndexBuff_caraInferior[0] = 0;
	this->m_IndexBuff_caraInferior[1] = 1;
	this->m_IndexBuff_caraInferior[2] = 2;
	this->m_IndexBuff_caraInferior[3] = 1;
	this->m_IndexBuff_caraInferior[4] = 2;
	this->m_IndexBuff_caraInferior[5] = 5;

	this->m_IndexBuff_caraInferior[6] = 2;
	this->m_IndexBuff_caraInferior[7] = 3;
	this->m_IndexBuff_caraInferior[8] = 9;
	this->m_IndexBuff_caraInferior[9] = 3;
	this->m_IndexBuff_caraInferior[10] = 9;
	this->m_IndexBuff_caraInferior[11] = 10;

	this->m_IndexBuff_caraInferior[12] = 6;
	this->m_IndexBuff_caraInferior[13] = 8;
	this->m_IndexBuff_caraInferior[14] = 10;
	this->m_IndexBuff_caraInferior[15] = 8;
	this->m_IndexBuff_caraInferior[16] = 10;
	this->m_IndexBuff_caraInferior[17] = 11;

	this->m_IndexBuff_caraInferior[18] = 7;
	this->m_IndexBuff_caraInferior[19] = 8;
	this->m_IndexBuff_caraInferior[20] = 5;
	this->m_IndexBuff_caraInferior[21] = 7;
	this->m_IndexBuff_caraInferior[22] = 5;
	this->m_IndexBuff_caraInferior[23] = 4;

	// Laterales externos, sus normales y sus indices
	this->m_vertices_lateralExterno[0] = glm::vec3(5.0f, -10.0f, -0.25f);
	this->m_vertices_lateralExterno[1] = glm::vec3(5.0f, -10.0f, 0.25f);
	this->m_vertices_lateralExterno[2] = glm::vec3(5.0f, 10.0f, -0.25f);
	this->m_vertices_lateralExterno[3] = glm::vec3(5.0f, 10.0f, 0.25f);

	for (int i = 0; i < 4; ++i) this->m_normales_lateralExterno[i] = glm::vec3(1.0f, 0.0f, 0.0f);

	this->m_IndexBuff_lateralExterno[0] = 0;
	this->m_IndexBuff_lateralExterno[1] = 1;
	this->m_IndexBuff_lateralExterno[2] = 2;
	this->m_IndexBuff_lateralExterno[3] = 1;
	this->m_IndexBuff_lateralExterno[4] = 2;
	this->m_IndexBuff_lateralExterno[5] = 3;

	//
	this->m_vertices_lateralExterno[4] = glm::vec3(5.0f, 10.0f, -0.25f);
	this->m_vertices_lateralExterno[5] = glm::vec3(5.0f, 10.0f, 0.25f);
	this->m_vertices_lateralExterno[6] = glm::vec3(-5.0f, 10.0f, -0.25f);
	this->m_vertices_lateralExterno[7] = glm::vec3(-5.0f, 10.0f, 0.25f);

	for (int i = 4; i < 8; ++i) this->m_normales_lateralExterno[i] = glm::vec3(0.0f, 1.0f, 0.0f);

	this->m_IndexBuff_lateralExterno[6] = 4;
	this->m_IndexBuff_lateralExterno[7] = 5;
	this->m_IndexBuff_lateralExterno[8] = 6;
	this->m_IndexBuff_lateralExterno[9] = 5;
	this->m_IndexBuff_lateralExterno[10] = 6;
	this->m_IndexBuff_lateralExterno[11] = 7;

	//
	this->m_vertices_lateralExterno[8] = glm::vec3(-5.0f, 10.0f, -0.25f);
	this->m_vertices_lateralExterno[9] = glm::vec3(-5.0f, 10.0f, 0.25f);
	this->m_vertices_lateralExterno[10] = glm::vec3(-5.0f, -10.0f, -0.25f);
	this->m_vertices_lateralExterno[11] = glm::vec3(-5.0f, -10.0f, 0.25f);

	for (int i = 8; i < 12; ++i) this->m_normales_lateralExterno[i] = glm::vec3(-1.0f, 0.0f, 0.0f);

	this->m_IndexBuff_lateralExterno[12] = 8;
	this->m_IndexBuff_lateralExterno[13] = 9;
	this->m_IndexBuff_lateralExterno[14] = 10;
	this->m_IndexBuff_lateralExterno[15] = 9;
	this->m_IndexBuff_lateralExterno[16] = 10;
	this->m_IndexBuff_lateralExterno[17] = 11;

	//
	this->m_vertices_lateralExterno[12] = glm::vec3(-5.0f, -10.0f, -0.25f);
	this->m_vertices_lateralExterno[13] = glm::vec3(-5.0f, -10.0f, 0.25f);
	this->m_vertices_lateralExterno[14] = glm::vec3(5.0f, -10.0f, -0.25f);
	this->m_vertices_lateralExterno[15] = glm::vec3(5.0f, -10.0f, 0.25f);

	for (int i = 8; i < 12; ++i) this->m_normales_lateralExterno[i] = glm::vec3(0.0f, -1.0f, 0.0f);

	this->m_IndexBuff_lateralExterno[18] = 12;
	this->m_IndexBuff_lateralExterno[19] = 13;
	this->m_IndexBuff_lateralExterno[20] = 14;
	this->m_IndexBuff_lateralExterno[21] = 13;
	this->m_IndexBuff_lateralExterno[22] = 14;
	this->m_IndexBuff_lateralExterno[23] = 15;

	// Laterales internos, sus normales y sus indices
	this->m_vertices_lateralInterno[0] = glm::vec3(4.0f, -9.0f, -0.25f);
	this->m_vertices_lateralInterno[1] = glm::vec3(4.0f, -9.0f, 0.25f);
	this->m_vertices_lateralInterno[2] = glm::vec3(4.0f, -6.0f, -0.25f);
	this->m_vertices_lateralInterno[3] = glm::vec3(4.0f, -6.0f, 0.25f);

	for (int i = 0; i < 4; ++i) this->m_normales_lateralInterno[i] = glm::vec3(-1.0f, 0.0f, 0.0f);

	this->m_IndexBuff_lateralInterno[0] = 0;
	this->m_IndexBuff_lateralInterno[1] = 1;
	this->m_IndexBuff_lateralInterno[2] = 2;
	this->m_IndexBuff_lateralInterno[3] = 1;
	this->m_IndexBuff_lateralInterno[4] = 2;
	this->m_IndexBuff_lateralInterno[5] = 3;

	//
	this->m_vertices_lateralInterno[4] = glm::vec3(4.0f, -6.0f, -0.25f);
	this->m_vertices_lateralInterno[5] = glm::vec3(4.0f, -6.0f, 0.25f);
	this->m_vertices_lateralInterno[6] = glm::vec3(1.0f, -6.0f, -0.25f);
	this->m_vertices_lateralInterno[7] = glm::vec3(1.0f, -6.0f, 0.25f);

	for (int i = 4; i < 8; ++i) this->m_normales_lateralInterno[i] = glm::vec3(0.0f, -1.0f, 0.0f);

	this->m_IndexBuff_lateralInterno[6] = 4;
	this->m_IndexBuff_lateralInterno[7] = 5;
	this->m_IndexBuff_lateralInterno[8] = 6;
	this->m_IndexBuff_lateralInterno[9] = 5;
	this->m_IndexBuff_lateralInterno[10] = 6;
	this->m_IndexBuff_lateralInterno[11] = 7;

	//
	this->m_vertices_lateralInterno[8] = glm::vec3(1.0f, -6.0f, -0.25f);
	this->m_vertices_lateralInterno[9] = glm::vec3(1.0f, -6.0f, 0.25f);
	this->m_vertices_lateralInterno[10] = glm::vec3(1.0f, -9.0f, -0.25f);
	this->m_vertices_lateralInterno[11] = glm::vec3(1.0f, -9.0f, 0.25f);

	for (int i = 8; i < 12; ++i) this->m_normales_lateralInterno[i] = glm::vec3(1.0f, 0.0f, 0.0f);

	this->m_IndexBuff_lateralInterno[12] = 8;
	this->m_IndexBuff_lateralInterno[13] = 9;
	this->m_IndexBuff_lateralInterno[14] = 10;
	this->m_IndexBuff_lateralInterno[15] = 9;
	this->m_IndexBuff_lateralInterno[16] = 10;
	this->m_IndexBuff_lateralInterno[17] = 11;

	//
	this->m_vertices_lateralInterno[12] = glm::vec3(1.0f, -9.0f, -0.25f);
	this->m_vertices_lateralInterno[13] = glm::vec3(1.0f, -9.0f, 0.25f);
	this->m_vertices_lateralInterno[14] = glm::vec3(4.0f, -9.0f, -0.25f);
	this->m_vertices_lateralInterno[15] = glm::vec3(4.0f, -9.0f, 0.25f);

	for (int i = 12; i < 16; ++i) this->m_normales_lateralInterno[i] = glm::vec3(0.0f, 1.0f, 0.0f);

	this->m_IndexBuff_lateralInterno[18] = 12;
	this->m_IndexBuff_lateralInterno[19] = 13;
	this->m_IndexBuff_lateralInterno[20] = 14;
	this->m_IndexBuff_lateralInterno[21] = 13;
	this->m_IndexBuff_lateralInterno[22] = 14;
	this->m_IndexBuff_lateralInterno[23] = 15;
}


void Losa::renderizar(const glm::mat4 &matVista, const glm::mat4 &matProyeccion, const glm::mat4 &matModelo) const {
	// Carga el shader
	Renderizable::cargarShaderProgram();

	// Empieza a dibujar todo
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);

	// Los datos de iluminacion
	Renderizable::cargarDatosIluminacion(matModelo);

	// Las matrices de transformacion
	Renderizable::cargarMatricesTransformacion(matVista, matProyeccion, matModelo);

	// Las caras
	glVertexPointer(3, GL_FLOAT, 0, this->m_vertices_caraSuperior);
	glNormalPointer(GL_FLOAT, 0, this->m_normales_caraSuperior);
	glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, this->m_IndexBuff_caraSuperior);

	glVertexPointer(3, GL_FLOAT, 0, this->m_vertices_caraInferior);
	glNormalPointer(GL_FLOAT, 0, this->m_normales_caraInferior);
	glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, this->m_IndexBuff_caraInferior);

	// Los laterales
	glVertexPointer(3, GL_FLOAT, 0, this->m_vertices_lateralExterno);
	glNormalPointer(GL_FLOAT, 0, this->m_normales_lateralExterno);
	glDrawElements(GL_TRIANGLE_STRIP, 24, GL_UNSIGNED_INT, this->m_IndexBuff_lateralExterno);

	glVertexPointer(3, GL_FLOAT, 0, this->m_vertices_lateralInterno);
	glNormalPointer(GL_FLOAT, 0, this->m_normales_lateralInterno);
	glDrawElements(GL_TRIANGLE_STRIP, 24, GL_UNSIGNED_INT, this->m_IndexBuff_lateralInterno);

	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY);
}

